package com.revoltingdevelopment.perquackey;
import java.util.*;
/**
 * WordChart
 */
public class WordChart {

	public WordChart() {}

	public int getScore() {

		int theScore = 0;

		for (int col = 0; col < 8; col++) {
			boolean wordFound = false;
			for (int row = 4; row >= 0 && !wordFound; row--) {
				if (!words[row][col].equals("")) {
					wordFound = true;
					theScore += pointValues[row][col];
				}
			}
		}

		if (!words[4][0].equals("") && !words[4][1].equals("")) {
			theScore += 300;
		}

		if (!words[4][1].equals("") && !words[4][2].equals("")) {
			theScore += 500;
		}

		if (!words[4][2].equals("") && !words[4][3].equals("")) {
			theScore += 800;
		}

		if (!words[4][3].equals("") && !words[4][4].equals("")) {
			theScore += 1200;
		}

		if (!words[4][4].equals("") && !words[4][5].equals("")) {
			theScore += 1850;
		}

		return theScore;
	}

	public boolean addWord(String word, PerquackeyDiceCupAlt cup, int score, TreeSet<String> theDictionary) {

		boolean vulnerable = (score >= 2000) ? true : false;

		int wordLen = word.length();

		if (vulnerable) {
			if ((wordLen < 4) || (wordLen > 10)) {
				this.statusMsg = ERR_LENGTH_VULNERABLE;
				return false;
			}
		}
		else {
			if ((wordLen < 3) || (wordLen > 10)) {
				this.statusMsg = ERR_LENGTH;
				return false;
			}
		}
		
		String myWord = word.toUpperCase().trim();

		// Try to match each letter in the word with a letter in the cup.

		ArrayList<Character> theLetters = new ArrayList<Character>(cup.getDice(vulnerable).length);

		ArrayList<PerquackeyDieAlt> allDice =
			new ArrayList<PerquackeyDieAlt>(Arrays.asList(cup.getDice(vulnerable)));

		for (PerquackeyDieAlt theDie : allDice) {
			theLetters.add(theDie.getLetter());
		}

		for (int i = 0; i < wordLen; i++) {
			Character theChar = new Character(myWord.charAt(i));
			if (theLetters.contains(theChar)) {
				theLetters.remove(theChar);
			}
			else {
				this.statusMsg = ERR_INVALID_LETTER;
				return false;
			}
		}

		if (this.wordUsed(myWord)) {
			this.statusMsg = ERR_DUPLICATE;
			return false;
		}

		if (myWord.endsWith("S")) {
			String singular = myWord.substring(0, myWord.length() - 1);
			if (this.wordUsed(singular)) {
				this.statusMsg = ERR_S_PLURAL;
				return false;
			}
		}
		else {
			String plural = myWord + "S";
			if (this.wordUsed(plural)) {
				this.statusMsg = ERR_S_SINGULAR;
				return false;
			}
		}

		if (!theDictionary.contains(myWord)) {
			this.statusMsg = ERR_DICTIONARY;
			return false;
		}

		boolean wordAdded = false;
		int col = wordLen - 3;
		int maxRow = (wordLen == 10) ? 3 : 5;

		for (int row = 0; (row < maxRow) && (!wordAdded); row++) {
			if (words[row][col].equals("")) {
				words[row][col] = myWord;
				wordAdded = true;
			}
		}

		if (!wordAdded) {
			this.statusMsg = ERR_COLUMN_FULL;
			return false;
		}
			
		this.statusMsg = MSG_WORD_ADDED;
		return true;
	}

	public void removeWord(String word) {

		String myWord = word.toUpperCase().trim();

		for (int row = 0; row < 5; row++) {
			for (int col = 0; col < 8; col++) {
				if (words[row][col].equals(myWord)) {
					words[row][col] = "";
				}
			}
		}

		this.eliminateGaps();
		return;
	}

	public void eliminateGaps() {

		for (int row = 4; row > 0; row--) {
			for (int col = 0; col < 8; col++) {
				if (!words[row][col].equals("") && words[row - 1][col].equals("")) {
					words[row - 1][col] = words[row][col];
					words[row][col] = "";
				}
			}
		}

		return;
	}

	public boolean wordUsed(String word) {

		boolean wordFound = false;

		String myWord = word.toUpperCase().trim();

		for (int row = 0; row < 5 && !wordFound; row++) {
			for (int col = 0; col < 8 && !wordFound; col++) {
				if (myWord.equals(words[row][col])) {
					wordFound = true;
				}
			}
		}

		return wordFound;
	}

	public String[][] getWordChart() {

		int rows = words.length;
		int cols = words[0].length;
		String[][] copyChart = new String[rows][cols];

		for (int row = 0; row < 5; row++) {
			copyChart[row] = Arrays.copyOf(words[row], cols);
		}

		return copyChart;
	}

	public String toString() {

		StringBuilder theString = new StringBuilder();
		theString.append(this.getClass().getName());
		theString.append("\nPoints Table\n");

		for (int row = 0; row < 5; row++) {
			for (int col = 0; col < 8; col++) {
				theString.append(pointValues[row][col]);
				theString.append("\t");
			}
			theString.append("\n");
		}

		theString.append("Words Table\n");

		for (int row = 0; row < 5; row++) {
			for (int col = 0; col < 8; col++) {
				theString.append(words[row][col]);
				theString.append("\t");
			}
			theString.append("\n");
		}

		return theString.toString();
	}

	public String getStatusMsg() {

		return this.statusMsg;
	}
	
	private int pointValues[][] = {
		{ 60, 120, 200, 300, 500 , 750 , 1000 , 1500},
		{ 70, 140, 250, 400, 650, 1000, 1500, 3000},
		{ 80, 160, 300, 500, 800, 1250, 2000, 5000},
		{ 90, 180, 350, 600, 950, 1500, 2500, 0},
		{ 100, 200, 400, 700, 1100, 1750, 3000, 0}
	};

	private String words[][] = {
		{ "", "", "", "", "", "", "", ""},
		{ "", "", "", "", "", "", "", ""},
		{ "", "", "", "", "", "", "", ""},
		{ "", "", "", "", "", "", "", ""},
		{ "", "", "", "", "", "", "", ""}
	};

	private String statusMsg = new String();
	private static String MSG_WORD_ADDED = "Word added to chart";
	private static String ERR_LENGTH = "Words must be from 3 to 10 letters";
	private static String ERR_LENGTH_VULNERABLE = "Words must be from 4 to 10 letters";
	private static String ERR_INVALID_LETTER = "Words must use letters in cup";
	private static String ERR_COLUMN_FULL = "No more room for words of that length";
	private static String ERR_DUPLICATE = "Cannot use same word more than once per turn";
	private static String ERR_S_PLURAL = "Cannot add same word plus letter 'S'";
	private static String ERR_S_SINGULAR = "Cannot add same word minus letter 's'";
	private static String ERR_DICTIONARY = "Word not in dictionary";

	public static void main(String[] args) {

		System.out.println("Start WordChart test.");
		TreeSet<String> theDictionary = new TreeSet<String>();
		PerquackeyDiceCupAlt theCup = new PerquackeyDiceCupAlt();
		WordChart theChart = new WordChart();
		if (theChart.addWord("aa", theCup, 1000, theDictionary)) {
			System.out.println("Word added successfully.");
		}
		else {
			System.out.println("Word not added.");
		}
		System.out.println(theChart.getStatusMsg());
		if (theChart.addWord("cat", theCup, 1000, theDictionary)) {
			System.out.println("Word added successfully.");
		}
		else {
			System.out.println("Word not added.");
		}
		System.out.println(theChart.getStatusMsg());
		if (theChart.addWord("aaaaaaaaaaa", theCup, 2000, theDictionary)) {
			System.out.println("Word added successfully.");
		}
		else {
			System.out.println("Word not added.");
		}
		System.out.println(theChart.getStatusMsg());
		System.out.println("Score: " + theChart.getScore());
		String[][] copiedChart = theChart.getWordChart();
		for (int row = 0; row < copiedChart.length; row++) {
			for (int col = 0; col < copiedChart[row].length; col++) {
				System.out.println("Row: " + row + " Col: " + col + " Word: " +
							copiedChart[row][col]);
			}
		}
		System.out.println("End WordChart test.");
	}
}
